#include "../server.h"

extern SVC_FUNC(HELLO);

extern SVC_FUNC(CREATE);
extern SVC_FUNC(GET);
extern SVC_FUNC(DESTROY);
extern SVC_FUNC(VALIDATE);
extern SVC_FUNC(PUTKEY);
extern SVC_FUNC(GETKEY);
extern SVC_FUNC(MODKEY);
extern SVC_FUNC(DESTROYKEY);
extern SVC_FUNC(ENCRYPT);
extern SVC_FUNC(DECRYPT);

static struct _svc_map
{/*{{{*/
    char *name;
    P_SVC_FUNC p_func;
}/*}}}*/
svc_map[]=
{/*{{{*/
    { "CREATE", SVC_FUNC_CREATE },
    { "GET", SVC_FUNC_GET },
    { "DESTROY", SVC_FUNC_DESTROY },
    { "VALIDATE", SVC_FUNC_VALIDATE },
    { "PUTKEY", SVC_FUNC_PUTKEY },
    { "GETKEY", SVC_FUNC_GETKEY },
    { "MODKEY", SVC_FUNC_MODKEY },
    { "DESTROYKEY", SVC_FUNC_DESTROYKEY },
    { "ENCRYPT", SVC_FUNC_ENCRYPT },
    { "DECRYPT", SVC_FUNC_DECRYPT },
    { "HELLO", SVC_FUNC_HELLO }
};/*}}}*/
static const unsigned int MAPSIZE=
sizeof(svc_map)/sizeof(struct _svc_map);

int svc_init()
{/*{{{*/
    struct _svc_info *info;
    int i;

    pthread_mutex_init(&share_info.svc_info_lock, NULL);
    ALLOC_ARRAY_RETERR(share_info.svc_info, struct _svc_info, MAPSIZE,
            share_info.svc_num, RET_ERR_ALLOC);
    for(i=0; i<MAPSIZE; ++i)
    {
        info=&share_info.svc_info[i];
        info->name=svc_map[i].name;
        info->loop=0;
        info->count=0;
    }
    return(0);
}/*}}}*/

int svc_call(struct worker_ctl *worker_ctl, char *msg_in)
{/*{{{*/
    int worker_idx=worker_ctl->worker_idx;
    struct _svc_map *map=NULL;
    char *msg_out=worker_ctl->msg_out;
    char *body;
    char *svc;
    int res;
    int svc_idx;
    int rtn;

    CLR_BUF(msg_out);
    body=msg_in;
    if((svc=para_get_item(msg_in, &body)) == NULL ||
            (res=strlen(svc)) <= 0 || res > NAME_SIZE)
    {
        errlog("%s %s: worker(%d) svc(%s) invalid",
                __FILE__, __func__, worker_idx, (svc)?svc:SPACES);
		para_put_item(msg_out, SOAR_ERR_SVC_INVALID);
        return(atoi(SOAR_ERR_SVC_INVALID));
    }

    for(svc_idx=0; svc_idx<MAPSIZE; ++svc_idx)
    {
        map=&svc_map[svc_idx];
        if(strcasecmp(map->name, svc) == 0) break;
    }
    if(svc_idx == MAPSIZE)
    {
        errlog("%s %s: worker(%d) proc_(%s) not found",
                __FILE__, __func__, worker_idx, svc);
        para_put_item(msg_out, SOAR_ERR_SVC_NOT_FOUND);
        rtn=atoi(SOAR_ERR_SVC_NOT_FOUND);
    }
    else
    {
        rtn=map->p_func(worker_idx, body, msg_out);
        ++worker_ctl->svc_count[svc_idx];
    }

    return(rtn);
}/*}}}*/
